package com.study.flink.java.day08_tableAPI;

import org.apache.flink.api.common.functions.FilterFunction;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.java.StreamTableEnvironment;
import org.apache.flink.types.Row;
import org.apache.flink.util.Collector;

import java.util.Arrays;

/**
 * Flink Table API单词计数示例
 * @author linys
 */
public class StreamSqlWordCountDemo {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        // 创建一个实时Table执行上下文
        StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
        // words: spark hadoop flink
        DataStreamSource<String> lines = env.socketTextStream("node02", 8888);
        // 转化为结构化数据
        SingleOutputStreamOperator<String> words = lines.flatMap(
                (FlatMapFunction<String, String>) (line, out) -> Arrays.stream(line.split("\\W+"))
                        .forEach(out::collect)).returns(Types.STRING);
        // 将DataStream注册成表
        Table table = tableEnv.fromDataStream(words, "word");
        // 写SQL，分组，聚合，支持DSL的链式编程
        Table result = table.groupBy("word").select("word, count(1) as counts");
        // 转换成可更新的数据流
        DataStream<Tuple2<Boolean, Row>> dataStream = tableEnv.toRetractStream(result, Row.class)
                .filter(new FilterFunction<Tuple2<Boolean, Row>>() { // 过滤旧的false数据
            @Override
            public boolean filter(Tuple2<Boolean, Row> tp) throws Exception {
                return tp.f0;
            }
        });
        dataStream.print();
        env.execute("StreamSqlWordCountDemo");
    }
}
